import { sep } from 'node:path';
import { fileURLToPath, URL } from 'node:url';
import { accessSync, readdirSync } from 'node:fs';

export const resolve = (src: string) => fileURLToPath(new URL(`../${src}`, import.meta.url));

export const getSep = (src: string) => resolve(src).split(sep).join('/');

interface AccessType {
  name: string;
  dir: string;
  extensions: string[];
}
const access = ({ name, dir, extensions }: AccessType) => {
  const paths = ['/Index', '/index', `/${name}`].reduce(
    (t: string[], o: string) => [...t, ...extensions.map((r) => `${o}.${r}`)],
    [],
  );

  for (const path of paths) {
    try {
      accessSync(`${getSep('src')}/${dir}/${name}${path}`);
      return path;
    } catch {}
  }
  return undefined;
};

// 解决 nodejs 大小写不敏感不能正确读取路径，vite 的自动导入组件不能热更新
interface PathParams {
  folder: string;
}
export const getPath = (parentPath: string, { folder }: PathParams) => {
  try {
    const files = readdirSync(parentPath);
    for (const file of files) {
      if (file.toLowerCase() === folder) {
        return `${parentPath}/${file}`;
      }
    }
  } catch {}
  throw new Error(`${parentPath}/${folder} is exist?`);
};

export const setResolve = (name: string, { prefix = 'Eo', dir = 'components' } = {}) => {
  const partialName = name.slice(prefix.length);
  const path = access({ name: partialName, dir, extensions: ['vue', 'js'] }) || '.vue';
  return `${getSep('src')}/${dir}/${partialName}${path}`;
};

// resolver
export const layoutsResolver = () => (name: string) => {
  if (name.startsWith('Layout')) {
    return setResolve(name, { prefix: 'Layout', dir: 'layouts' });
  }
};

// 本地服务器配置
export const setServerConfig =
  ({ env }: { env: Record<string, string> }) =>
  (opts = {}): Record<string, any> => {
    return {
      port: Number(env.APP_PORT),
      proxy: {
        [env.EO_API_URL]: {
          target: env.API_PROXY,
          changeOrigin: true,
          rewrite: (path: string) => path.replace(env.EO_API_URL, ''),
        },
      },
      ...opts,
    };
  };
